package com.lfy.fyadmin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lfy.fyadmin.common.BusinessException;
import com.lfy.fyadmin.common.ErrorCode;
import com.lfy.fyadmin.dto.MenuTreeNode;
import com.lfy.fyadmin.dto.UserMenuResponse;
import com.lfy.fyadmin.entity.*;
import com.lfy.fyadmin.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单服务实现类
 */
@Service
public class MenuServiceImpl implements MenuService {
    
    private final UserService userService;
    private final PermissionService permissionService;
    private final UserRoleService userRoleService;
    private final RoleService roleService;
    private final RolePermissionService rolePermissionService;
    private final UserGroupService userGroupService;
    private final GroupPermissionService groupPermissionService;
    
    public MenuServiceImpl(UserService userService, 
                          PermissionService permissionService,
                          UserRoleService userRoleService,
                          RoleService roleService,
                          RolePermissionService rolePermissionService,
                          UserGroupService userGroupService,
                          GroupPermissionService groupPermissionService) {
        this.userService = userService;
        this.permissionService = permissionService;
        this.userRoleService = userRoleService;
        this.roleService = roleService;
        this.rolePermissionService = rolePermissionService;
        this.userGroupService = userGroupService;
        this.groupPermissionService = groupPermissionService;
    }
    
    @Override
    public UserMenuResponse getCurrentUserMenu() {
        // 获取当前登录用户ID
        if (!StpUtil.isLogin()) {
            throw new BusinessException(ErrorCode.UNAUTHORIZED, "用户未登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        return getUserMenuByUserId(userId);
    }
    
    @Override
    public UserMenuResponse getUserMenuByUserId(Long userId) {
        // 查询用户信息
        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "用户不存在");
        }
        
        // 获取用户的所有权限ID
        Set<Long> permissionIds = getUserPermissionIds(userId);
        
        // 获取用户的角色信息
        List<String> roles = getUserRoles(userId);
        
        // 构建菜单树
        List<MenuTreeNode> menuTree = buildMenuTree(new ArrayList<>(permissionIds));
        
        // 获取所有权限编码
        List<String> permissions = getPermissionCodes(permissionIds);
        
        // 构建响应
        UserMenuResponse response = new UserMenuResponse();
        response.setUserId(userId);
        response.setUsername(user.getUsername());
        response.setMenuTree(menuTree);
        response.setPermissions(permissions);
        response.setRoles(roles);
        
        return response;
    }
    
    @Override
    public List<MenuTreeNode> getAllMenuTree() {
        // 查询所有启用的菜单权限
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Permission::getType, 1) // 只查询菜单类型
                   .eq(Permission::getStatus, 1) // 只查询启用状态
                   .orderByAsc(Permission::getSort, Permission::getId);
        
        List<Permission> permissions = permissionService.list(queryWrapper);
        
        return buildMenuTreeFromPermissions(permissions);
    }
    
    @Override
    public List<MenuTreeNode> buildMenuTree(List<Long> permissionIds) {
        if (CollectionUtils.isEmpty(permissionIds)) {
            return new ArrayList<>();
        }
        
        // 查询权限信息
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Permission::getId, permissionIds)
                   .eq(Permission::getType, 1) // 只查询菜单类型
                   .eq(Permission::getStatus, 1) // 只查询启用状态
                   .orderByAsc(Permission::getSort, Permission::getId);
        
        List<Permission> permissions = permissionService.list(queryWrapper);
        
        return buildMenuTreeFromPermissions(permissions);
    }
    
    /**
     * 获取用户的所有权限ID（包括角色权限和用户组权限）
     */
    private Set<Long> getUserPermissionIds(Long userId) {
        Set<Long> permissionIds = new HashSet<>();
        
        // 1. 通过用户角色获取权限
        List<UserRole> userRoles = userRoleService.list(
            new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId)
        );
        
        if (!CollectionUtils.isEmpty(userRoles)) {
            List<Long> roleIds = userRoles.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());
            
            // 查询角色权限
            List<RolePermission> rolePermissions = rolePermissionService.list(
                new LambdaQueryWrapper<RolePermission>().in(RolePermission::getRoleId, roleIds)
            );
            
            Set<Long> rolePermissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toSet());
            
            permissionIds.addAll(rolePermissionIds);
        }
        
        // 2. 通过用户组获取权限
        List<UserGroup> userGroups = userGroupService.list(
            new LambdaQueryWrapper<UserGroup>().eq(UserGroup::getUserId, userId)
        );
        
        if (!CollectionUtils.isEmpty(userGroups)) {
            List<Long> groupIds = userGroups.stream()
                .map(UserGroup::getGroupId)
                .collect(Collectors.toList());
            
            // 查询组权限
            List<GroupPermission> groupPermissions = groupPermissionService.list(
                new LambdaQueryWrapper<GroupPermission>().in(GroupPermission::getGroupId, groupIds)
            );
            
            Set<Long> groupPermissionIds = groupPermissions.stream()
                .map(GroupPermission::getPermissionId)
                .collect(Collectors.toSet());
            
            permissionIds.addAll(groupPermissionIds);
        }
        
        return permissionIds;
    }
    
    /**
     * 获取用户的角色列表
     */
    private List<String> getUserRoles(Long userId) {
        List<UserRole> userRoles = userRoleService.list(
            new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId)
        );
        
        if (CollectionUtils.isEmpty(userRoles)) {
            return new ArrayList<>();
        }
        
        List<Long> roleIds = userRoles.stream()
            .map(UserRole::getRoleId)
            .collect(Collectors.toList());
        
        List<Role> roles = roleService.list(
            new LambdaQueryWrapper<Role>()
                .in(Role::getId, roleIds)
                .eq(Role::getStatus, 1)
        );
        
        return roles.stream()
            .map(Role::getCode)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取权限编码列表
     */
    private List<String> getPermissionCodes(Set<Long> permissionIds) {
        if (CollectionUtils.isEmpty(permissionIds)) {
            return new ArrayList<>();
        }
        
        List<Permission> permissions = permissionService.list(
            new LambdaQueryWrapper<Permission>()
                .in(Permission::getId, permissionIds)
                .eq(Permission::getStatus, 1)
        );
        
        return permissions.stream()
            .map(Permission::getCode)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    }
    
    /**
     * 从权限列表构建菜单树
     */
    private List<MenuTreeNode> buildMenuTreeFromPermissions(List<Permission> permissions) {
        if (CollectionUtils.isEmpty(permissions)) {
            return new ArrayList<>();
        }
        
        // 转换为MenuTreeNode
        List<MenuTreeNode> allNodes = permissions.stream()
            .map(this::convertToMenuTreeNode)
            .collect(Collectors.toList());
        
        // 构建树形结构
        List<MenuTreeNode> menuTree = buildTree(allNodes, null, 0);
        
        // 计算树的统计信息
        calculateTreeStats(menuTree);
        
        return menuTree;
    }
    
    /**
     * 转换Permission为MenuTreeNode
     */
    private MenuTreeNode convertToMenuTreeNode(Permission permission) {
        MenuTreeNode node = new MenuTreeNode();
        BeanUtils.copyProperties(permission, node);
        
        // 初始化默认值
        node.setHasChildren(false);
        node.setIsLeaf(true);
        node.setLevel(0);
        
        // 构建完整路径
        if (permission.getPath() != null) {
            node.setFullPath(permission.getPath());
        }
        
        return node;
    }
    
    /**
     * 递归构建树形结构
     */
    private List<MenuTreeNode> buildTree(List<MenuTreeNode> allNodes, Long parentId, int level) {
        // 创建父节点路径映射，用于构建完整路径
        Map<Long, String> parentPathMap = allNodes.stream()
            .filter(node -> node.getPath() != null)
            .collect(Collectors.toMap(MenuTreeNode::getId, MenuTreeNode::getPath, (v1, v2) -> v1));
        
        List<MenuTreeNode> children = allNodes.stream()
            .filter(node -> Objects.equals(node.getParentId(), parentId))
            .sorted(Comparator.comparing(MenuTreeNode::getSort, Comparator.nullsLast(Comparator.naturalOrder()))
                   .thenComparing(MenuTreeNode::getId))
            .collect(Collectors.toList());
        
        for (MenuTreeNode child : children) {
            // 设置层级信息
            child.setLevel(level);
            
            // 设置父节点路径
            if (parentId != null && parentPathMap.containsKey(parentId)) {
                child.setParentPath(parentPathMap.get(parentId));
            }
            
            // 递归构建子节点
            List<MenuTreeNode> grandChildren = buildTree(allNodes, child.getId(), level + 1);
            child.setChildren(grandChildren);
            
            // 设置子节点相关属性
            boolean hasChildren = !CollectionUtils.isEmpty(grandChildren);
            child.setHasChildren(hasChildren);
            child.setIsLeaf(!hasChildren);
            
            // 如果没有子节点，清空children列表以减少JSON大小
            if (!hasChildren) {
                child.setChildren(new ArrayList<>());
            }
        }
        
        return children;
    }
    
    /**
     * 计算菜单树的统计信息
     */
    private void calculateTreeStats(List<MenuTreeNode> menuTree) {
        for (MenuTreeNode node : menuTree) {
            calculateNodeStats(node);
        }
    }
    
    /**
     * 递归计算节点统计信息
     */
    private void calculateNodeStats(MenuTreeNode node) {
        if (node.getChildren() != null && !node.getChildren().isEmpty()) {
            for (MenuTreeNode child : node.getChildren()) {
                calculateNodeStats(child);
            }
        }
    }
}